/**
 *	defined the main entry environment and main programe
 *  VisualGroup JavaScript Classes, version 0.1
 *  (c) 2008 Bill Vison <vison_ruan@126.com>
 *
 *
/*--------------------------------------------------------------------------*/

/** define global js client variable */
window.$__SERVER = {
	prefix:getRootScriptContent()
};



/**
 * defined using method
 */
using = function($className) {
	try {
		Vsg.using($className);
	} catch ( ex ) {
		alert( "Occur error in using method : " + ex );
	}
}

/**
 * Threads Manage mechanism defined
 *
 */
ThreadsManagerMechanism = {
	__threads:[],
	_threadId:0 , 
	
	addThread:function($thread) {
		this.__threads.push($thread);
	},
	removeThread:function($thread) {
		this.__threads.remove($thread);
	},
	runComponent:function() {

		var $thisThreads = this.__threads;
		var $this = this;
		var running = function () {
			try {
				// ---- check the state ---
				for (var $i = 0 ; $i < $thisThreads.length ; $i++) {
					var $thread = $thisThreads[$i];

					var $timeOutId = 0;
					
					// --- run the exec thread 
					var execThread = function() {

						if ($thread.getState() == Thread.STOP) {
							$this.removeThread($thread);
						}
						else if ($thread.getState() == Thread.READY) {
							
							$thread._setState(Thread.RUNNING);
							try {
						
								$thread.fireEvent("runHandle",$thread);
							} catch (ex) {
								throw new Thread.ThreadException("执行线程出错，线程ID:" + $timeOutId , null , Thread.ThreadException.ExecRunError);
							} finally {
								// --- handle sleep ---
								if ($thread.getState() == Thread.RUNNING) {
									$thread._setState( Thread.STOP );
								} 
							}
						}
						else if ($thread.getState() == Thread.RUNNING) {
							
							// --- check the class run finish --
							if ($thread._sleepran && $thread._ran) {
								$thread._setState( Thread.STOP );
							}
						}
						else if ($thread.getState() == Thread.SLEEP) {
							try {
								$thread.fireEvent("sleep");
								$thread.fireEvent("afterSleep");	
							} catch (ex) {
								throw new Thread.ThreadException("睡眼线程出错，线程ID:" + $timeOutId , null , Thread.ThreadException.ExecRunError);
							} finally {
								
							}
							
						}						
						
						clearTimeout($timeOutId);
						
					};
					// execute thread every time defined
					$timeOutId = setTimeout(execThread,1);
					$thread._setId($timeOutId);					
				}
			} catch (ex) {
				// ignore the exception
				Ext.log("out : " + ex);
			} finally {
				//$thread = null;
			}
			
			
		};
		// --- check the defined ---
		this._threadId = setInterval(running , 1);
	},
	stopComponent:function() {
		clearInterval(this._threadId);
	}
	
};


/**
 * 	Script loader manager factory
 *	This's a single manager factory.
 */
var ClassLoaderManagerFactory = {
	_manager:null,
	
	getManager:function() {
		var $manager ;
		try {
			$manager = new ClassLoaderManager();
			this._manager = (this.manager == null) ? $manager : this._manager;
		} catch (ex) {
			throw new Exception.SysException("创建\"ClassLoaderManager\"对像出错! ", null , Exception.SysException.CreateObjectError);
		}

		return this._manager;
	}
};



/**
 * 	Script loader global handle defined
 */
var ScriptLoaderGlobalHandle = {
	
	findUsingImport : function( $str ) {
		var $usingImport = [];
		/**
	 	* the last chara means global research cachea
	 	*/
		var $termExp = new RegExp("using\\(\"[a-zA-Z]+[a-zA-Z\.]*\"\\)" ,"g");
		var $result = null;
		var $className = null;
		try {

			while ( ($result = $termExp.exec($str) ) != null ) {
				$className = $result[0].substring(7 , $result[0].length-2);
				$usingImport.push($className);
			}
		
		} catch (ex) {
			Ext.log(ex);	
		} finally {
			$className = null;
			$result = null;
			delete $termExp;
		}
		return $usingImport;		
	},

	/**
	 * Remove the "using class "string in the script
 	* @param {string} [$scriptContent] The script need to remove "using(class)"
 	*/
	scriptWithOutUsing : function( $org ) {
		/**
	 	* the last chara means global research cachea
	 	*/
		var $termExp = new RegExp("using\\(\"[a-zA-Z]+[a-zA-Z\.]*\"\\);" ,"g");
		var $result = null;
		var $className = null;
		try {
			while ( ($result = $termExp.exec($org) ) != null ) {
				$org = $org.replace($termExp,"");
			}
		} catch (ex) {
			Ext.log("error in [ScriptLoaderGlobalHandle.scriptWithOutUsing] : " + ex);	
		} finally {
			$result = null;
			$className = null;
			delete $termExp;
		}
		return $org;		
	},
	
	/**
	 * execute script source .
	 */
	execScriptCode : function ( $source ) {
		try {
			(Ext.isIE) ? execScript($source) : eval($source);
		} catch (ex) {
			throw new Exception.SysException("Compile error :" , null , Exception.SysException.ExecScriptError);
		}			
	},
	
	execScript : function( $orgClasses ) {
		
		// --- defined exec class ---
		function execClass($key , $map) {

			var $classState = $map.get($key);

			if ($classState.state == LoadClassState.LOADED) {

				if ($classState.dependentClasses != null && $classState.dependentClasses.length > 0) {
					var $hadLoad = true;
					for (var $i = 0 ; $i < $classState.dependentClasses.length ; $i++) {
				
						var $dependClassState = $map.get($classState.dependentClasses[$i]);
					
						if ( $dependClassState != null && $dependClassState.state == LoadClassState.LOADED) {

							$hadLoad = false;
							execClass($classState.dependentClasses[$i] , $map);

						}
					}
					
					// ---- handle ---
				
					if ($hadLoad) {
						
						try {
							ScriptLoaderGlobalHandle.execScriptCode($classState.source);
							$classState.state = LoadClassState.EXECUTED;
						} catch (ex) {
							throw new Exception.SysException("execute source: ["+$key+"]" , null , Exception.SysException.ExecScriptError);
						}
					
					}
				
				} else {
				
					try {
						ScriptLoaderGlobalHandle.execScriptCode($classState.source)
						$classState.state = LoadClassState.EXECUTED;
					} catch (ex) {
						throw new Exception.SysException("execute source:: ["+$key+"]" , null , Exception.SysException.ExecScriptError);
					}
					
				}
			}
		
		}		
		
		
	
		try {
			
			var $started = true;

			
			while ( $started ) {
				
				$orgClasses.eachKey(function($key) {
					execClass($key , $orgClasses);
				});		
		
				var $classState;
				// that will stop
				$started = false;
				for (var $i = 0 ; $i < $orgClasses.getCount() ; $i++ ) {
					$classState = $orgClasses.get($i);
					if ($classState.state == LoadClassState.LOADED) {
						$started = true;
						break;
					}
				}
			}
			
			
			
			
		} catch ( ex ) {
			
			if (ex instanceof Exception) {
				Ext.log("execute script in [exeScript] : " + ex.getLocalMessage());
			}
			
			throw ex;
			
		}

	}


};


/**
 * defined the Class Load State
 */
var LoadClassState = {
	INITIALIZE:0,
	FAIL:-1,
	LOADED : 1,
	EXECUTED : 2
};


/** 
 * 	Main program entry for the class, than not no name defned.
 *	This function will run when is load all data 
 */

(function() {
	// run thread manager ---
	ThreadsManagerMechanism.runComponent();
	
})();




